using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.ProjectWindowCallback;
using UnityEngine;
using Object = UnityEngine.Object;

public class NewEntitasComponentEditor  : MonoBehaviour
{
    class NewAssets : EndNameEditAction
    {
        public override void Action(int instanceId, string pathName, string resourceFile)
        {
            Object o = CreateScriptAssetFromTemplate(pathName, resourceFile);
            ProjectWindowUtil.ShowCreatedAsset(o);
        }
 
        internal static Object CreateScriptAssetFromTemplate(string pathName, string resourceFile)
        {
            string fullPath = Path.GetFullPath(pathName);
            string text = resourceFile + "";
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(pathName);
            text = Regex.Replace(text, "#NAME#", fileNameWithoutExtension);
            text = Regex.Replace(text, "#TIME#", (new DateTime(2017,11,7) - DateTime.Now).Days.ToString());
            bool encoderShouldEmitUTF8Identifier = true;
            bool throwOnInvalidBytes = false;
            UTF8Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier, throwOnInvalidBytes);
            bool append = false;
            StreamWriter streamWriter = new StreamWriter(fullPath, append, encoding);
            streamWriter.Write(text);
            streamWriter.Close();
            AssetDatabase.ImportAsset(pathName);
            return AssetDatabase.LoadAssetAtPath(pathName, typeof(Object));
        }
 
    }    
    [MenuItem("Assets/Create/C# Entitas Component", false, 91)]
    public static void CreateComp()
    {
        string tmpl = @"
using System.Collections;
using System.Collections.Generic;
using Entitas;
//Author 野山君
//项目持续时间 #TIME#
[Game]
public class #NAME# : IComponent
{
    //public string msg;
}
";
        ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0,
            ScriptableObject.CreateInstance<NewAssets>(),
            GetSelectedPathOrFallback() + "/EntitasComonent.cs",
            null,tmpl);
    }
 
    [MenuItem("Assets/Create/C# Entitas System", false, 92)]
    public static void CreateSystem()
    {
        string tamlEmtySys = @"
using Entitas;

//Author 野山君
//项目持续时间 #TIME#
public class #NAME# : IInitializeSystem
{ 
    // always handy to keep a reference to the context 
    // we're going to be interacting with it
    readonly GameContext _context;

    public #NAME#(Contexts contexts)
    { 
        // get the context from the constructor
        _context = contexts.game;
    }

    public void Initialize()
    {
        throw new System.NotImplementedException();
    }
}
";
        string tmplSystem = @"
using System.Collections.Generic;
using Entitas;

//Author 野山君
//项目持续时间 #TIME#
public class #NAME# : ReactiveSystem<GameEntity> {
 
    public DebugMessageSystem(Contexts contexts) : base(contexts.game)
    {
    }

    protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
    {
        throw new System.NotImplementedException();
    }

    protected override bool Filter(GameEntity entity)
    {
        throw new System.NotImplementedException();
    }

    protected override void Execute(List<GameEntity> entities)
    {
        throw new System.NotImplementedException();
    }
}
";
        Object obj = Selection.activeObject;
        string cmpName = "NewEntitas";
        bool isCmp = false;
        if (obj &&( obj is TextAsset))
        {
            cmpName = (obj as TextAsset).name;
            isCmp = true;
        }
        ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0,
            ScriptableObject.CreateInstance<NewAssets>(),
            GetSelectedPathOrFallback() + string.Format("/{0}System.cs",cmpName),
            null,isCmp ? tmplSystem : tamlEmtySys);
    }
    [MenuItem("Assets/Create/C# Entitas Feature", false, 93)]
    public static void CreateFeature()
    {
        string tmpl = @"
using Entitas;

//Author 野山君
//项目持续时间 #TIME#
public class #NAME# : Feature
{
    public #NAME#(Contexts contexts) : base ('#NAME#')
    {
        //Add(new HelloWorldSystem(contexts));
        //Add(new DebugMessageSystem(contexts));
    }
}";
        string Feature = "NewFeature.cs"; 
        ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0,
            ScriptableObject.CreateInstance<NewAssets>(),
            GetSelectedPathOrFallback() +"/"+ Feature,
            null,tmpl.Replace('\'','\"'));
    }
    public static string GetSelectedPathOrFallback()
    {
        string path = "Assets";
        foreach (Object obj in Selection.GetFiltered(typeof(Object), SelectionMode.Assets))
        {
            path = AssetDatabase.GetAssetPath(obj);
            if (!string.IsNullOrEmpty(path) && File.Exists(path))
            {
                path = Path.GetDirectoryName(path);
                break;
            }
        }
        return path;
    }
}